/*
TP1: Organizacion de Computadoras 66.20 (UBA)
Programa: unix2dos
MALDONADO, CABRERA, MUGICA.
*/
#include <mips/regdef.h>
#include <sys/syscall.h>

//#define O_RDONLY        0     /* open for reading only */
//#define O_WRONLY        1     /* open for writing only */
//#define O_CREATE       512

#ifndef O_RDONLY
#define O_RDONLY 0x00000000 /* open for reading only */
#endif

#ifndef O_WRONLY
#define O_WRONLY 0x00000001 /* open for writing only */
#endif

#ifndef O_CREAT
#define O_CREAT  0x00000200 /* create if nonexistent */
#endif

#ifndef O_TRUNC
#define O_TRUNC  0x00000400 /* truncate to zero length */
#endif

	.text
	.align 2
	.globl main
	.ent main

/*Encabezado del main:

  int main(int argc, char ∗∗argv)

*/

main:

/* Stack:

52	char** argv
48	int argc
      ---------------
44	////////////
40	     ra
36	     fp
32	     gp
28           s1
24	     s2
20	     s4
16           s5
       --------------
12
8
4
0
*/
	.frame $fp,48,ra
	.set noreorder
	.cpload t9
	.set reorder
	subu sp,sp,48
	.cprestore 32

	sw $fp,36(sp)
	sw ra,40(sp)

	move $fp,sp

	sw s1,28($fp)
	sw s2,24($fp)
	sw s4,20($fp)
	sw s5,16($fp)
	sw a0,48($fp)
	sw a1,52($fp)


/*------------Porceso los argumentos-------------------*/

/*
 * s1 contendra la entrada.
 * s2 contendra la salida.
*/

	/*Inicialmente los archivos de entrada y salida son los estandares*/
	li s1,0
	li s2,1
	li s4,2
	li s5,4

#El bucle recorre todos los argumentos. Primero compara con -i y despues con -o.
#Si no es ninguno de los 2 hay una error de parametro.
bucle:
	lw t2,48($fp)
	bgt s4,t2,inicio
	lw a1,52($fp)
	addu a0,a1,s5
	lw a0,0(a0)
	la a1,caracter_stdin
	jal mystrcmp
	beqz v0,Es_entrada
	lw a1,52($fp)
	addu a0,a1,s5
	lw a0,0(a0)
	la a1,caracter_stdout
	jal mystrcmp
	beqz v0,Es_salida
	j error_argumentos

/* Por convencion una ruta de archivo no puede comenzar con - */
# Salta si el argumento anterior fui -i. Verifica si tiene ruta de acceso y en tal caso abre el archivo para lectura
Es_entrada:
#Comparo el primer caracter de la posible ruta con el caracter guion.
	add s4,s4,1
	add s5,s5,4
	lw t2,48($fp)
	bgt s4,t2,inicio
	lw a0,52($fp)
	addu a0,a0,s5
	lw t0,0(a0)
	lb t1,0(t0)
	li t2,'-'
	beq t1,t2,estandar
#Si no fue guion, abro el archivo segun la ruta.
	li v0,SYS_open
	lw a0,52($fp)
	add a0,a0,s5
	lw a0,0(a0)
	li a1,O_RDONLY
	li a2,0
	syscall
#Verifico que la apertura fue correcta.
	bnez a3, error_aperturaEntrada
#Salvo el controlador de archivo devuelto
	move s1,v0
	add s4,s4,1
	add s5,s5,4
	b bucle
#Permite avanzar al siguiente argumento
estandar:
	add s4,s4,1
	add s5,s5,4
	b	bucle
# Salta si el argumento anterior fui -o. Verifica si tiene ruta de acceso y en tal caso abre el archivo para lectura
Es_salida:
#Comparo el primer caracter de la posible ruta con el caracter guion.
	add s4,s4,1
	add s5,s5,4
	lw t2,48($fp)
	bgt s4,t2,inicio
	lw a0,52($fp)
	add a0,a0,s5
	lw t0,0(a0)
	lb t1,0(t0)
	li t2,'-'
	beq t1,t2,estandar
#Si no fue guion, abro el archivo segun la ruta para escritura, si no existe lo creo.
	li v0,SYS_open
	lw a0,52($fp)
	add a0,a0,s5
    lw a0,0(a0)
	li a1, O_WRONLY|O_CREAT|O_TRUNC
	li a2,0
	syscall
#Verifico que la apertura fue correcta
	bnez a3, error_aperturaSalida
#Salvo el controlador del archivo
	move s2,v0
	add s4,s4,1
	add s5,s5,4
	b bucle
#Una vez procesados los argumentos llamo a la funcion  unix2dos
inicio:
	move a0,s1
	move a1,s2
	li a2,2
	jal unix2dos
	b salir
/*-------------------------Retornos-------------------------------------------------*/

error_lectura:
		li v0,SYS_write
		li a0,2
        la a1,msg_error_lectura
		li a2,14
		syscall
        li v0,1
		b salir

error_aperturaSalida:
		li v0, SYS_write
		li a0, 2
		la a1, msg_error_aperturaSalida
		li a2, 44
		syscall
 		li v0,1
		b salir

error_aperturaEntrada:
		li v0, SYS_write
		li a0,2
		la a1,msg_error_apertura
		li a2,36
		syscall
		li v0,1
		b salir


error_argumentos:
		li v0, SYS_write
		li a0, 2         # stderr
		la a1, msg_error_argumentos
		li a2, 29
		syscall
		li v0,1
		b salir

/*----------Reconstruccion del stack-------------------*/
/* Aclaracion: el v0 debe de venir cargado dado que se puede llegar a salir tanto desde dos2unix como de cualquiera de los errores */
salir:
#Cierro los archivos
	move s5,v0
	li v0,SYS_close
	move a0,s1
	syscall
	li v0,SYS_close
	move a0,s2
	syscall
	move v0,s5
#Reestablezco la pila
	move sp,$fp
	lw ra,40(sp)
	lw $fp,36(sp)
	lw gp,32(sp)
	lw s1,28(sp)
	lw s2,24(sp)
	lw s4,20(sp)
	lw s5,16(sp)
	addiu sp,sp,48

	jr ra

.end main

.rdata

/*--------Cadenas y caracteres---------*/
/*---Posibles caracteres de acceso-----*/
caracter_stdin:
	.asciiz "-i"
caracter_stdout:
	.asciiz "-o"
caracter_guion:
	.asciiz "-"
/*--------Mensajes de Error------------*/
msg_error_lectura:
	.asciiz "ERROR LECTURA\n"
msg_error_escritura:
	.asciiz "ERROR ESCRITURA\n"
msg_error_argumentos:
	.asciiz "ERROR ARGUMENTOS INCORRECTOS\n"
msg_error_apertura:
	.asciiz "ERROR ARCHIVO DE ENTRADA INCORRECTO\n"
msg_error_aperturaSalida:
	.asciiz "ERROR NO SE PUDO ABRIR EL ARCHIVO DE SALIDA\n"
